package student.aistar.day15.syn;

public class PlusNoAtomicityDemo implements Runnable {
    //场景一: 两个线程在一瞬间for循环全部执行完毕 -> i 一下子全部加到2000, 也有可能第一个线程走得快两个输出结果不一样
    //for循环次数 - 1000
    //Thread - 1 : 2000
    //Thread - 0 : 2000

    //场景二: 循环次数增加到100000
    //Thread-1: 15034
    //Thread-0: 19322 -> 最终i得结果

    //场景三: add方法 - synchronized 进行了修饰
    //Thread-0: 17521
    //Thread-1: 20000 -> 最终i得结果

    //T0进入了循环, T1进入了循环 -> 同时进来的
    //T0如果进入同步方法add(), 那么T1线程就会进入到同步阻塞[等待]
    //T0一旦执行完add方法之后, 那么就会自动释放锁
    //锁接下来的分配 - cpu去分配的 -> 锁分配给T0或者T1线程中得任意一个

    //T0优先把100000循环次数走完[i++] -> cpu调度T0得次数高于T1线程
    //T1线程实际上也有可能在这个过程中被分配到资源 -> 将进入add -> i++操作
    //T1线程被分配的cpu比较少 -> 同步阻塞得时间长一点点 - 循环走的比较慢

    int i = 0;
    @Override
    public void run() {
        for (int j = 0; j < 2000; j++) {
            //因为add方法没有进行同步 - sychronized修饰
            //两个线程都会进入到add方法中去执行i++操作
            add();
        }
        System.out.println(Thread.currentThread().getName() + ": " + i);
    }

    //1.当一个对象执行synchronized方法之后 -
    //1. 清空本地缓存的副本数据
    //2. 强制从主存中去再次获取副本 - 会再去读取最新的
    private synchronized void add() {
        i++;
//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
    }
    public static void main(String[] args) {
        Runnable r = new PlusNoAtomicityDemo();//俩个线程共享i
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        t1.start();
        t2.start();
    }
}
